package com.openlogic.logic.controller.logic;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import org.noear.solon.annotation.Body;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Delete;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Param;
import org.noear.solon.annotation.Path;
import org.noear.solon.annotation.Post;
import org.noear.solon.annotation.Put;
import org.noear.solon.auth.annotation.AuthPermissions;
import org.noear.solon.core.handle.Result;
import org.noear.solon.validation.annotation.Validated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.mybatisflex.core.paginate.Page;
import com.openlogic.api.logic.dto.RuleModelDto;
import com.openlogic.api.logic.dto.RuleSqlModelDto;
import com.openlogic.api.logic.entity.RuleModel;
import com.openlogic.api.logic.entity.RuleModelNodeMerge;
import com.openlogic.common.core.enums.BusinessType;
import com.openlogic.common.core.exception.logic.RuleException;
import com.openlogic.common.core.web.controller.BaseController;
import com.openlogic.common.core.web.domain.PageData;
import com.openlogic.common.datasource.annotation.QzLog;
import com.openlogic.logic.service.logic.RuleModelService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
* @ClassName: RuleModelController
* @Description: 决策参数Controller
* @author weiyongpeng
* @date 2024年7月14日 上午10:42:13
 */
@Api(value = "决策参数管理功能API")
@Controller
@Mapping("rule/model/variable")
public class RuleModelController extends BaseController {
	
	private static final Logger logger = LoggerFactory.getLogger(RuleModelController.class);
	
	@Inject
	private RuleModelService ruleModelService;
	
	/**
	* 描述：参数保存
	* @Title: saveRuleParam
	* @param ruleModel
	* @return
	* @author weiyongpeng
	* @date  2024年9月16日 上午9:51:13
	 */
	@ApiOperation(value = "决策私有参数保存")
	@Post
	@Mapping("saveRuleParam")
	@AuthPermissions("rule:variable:add")
	@QzLog(title = "决策私有参数保存", businessType = BusinessType.INSERT)
	public Result<String> saveRuleParam(@Validated @Body RuleModel ruleModel) {
		ruleModelService.insertRuleParam(ruleModel);
		return Result.succeed();
	}
	
	/**
	* 描述：校验节点参数是否被使用
	* @Title: checkParamIsUsedBySetting
	* @param ruleMode
	* @return
	* @author weiyongpeng
	* @date  2024年9月21日 上午9:22:41
	 */
	@ApiOperation(value = "校验节点参数是否被使用")
	@Post
	@Mapping("checkParamIsUsedBySetting")
	@AuthPermissions("rule:variable:list")
	@QzLog(title = "校验节点参数是否被使用", businessType = BusinessType.LIST)
	public Result<String> checkParamIsUsedBySetting(@Param("nodeJson") String nodeJson,@Param("modelIdentify") String modelIdentify) {
		try {
			boolean flag = this.checkParamIsUsed(nodeJson, modelIdentify);
			if (flag) {
				return Result.succeed("删除后关联的表达式需要重新配置");
			}
			return Result.succeed("请确认是否删除");
		} catch (Exception e) {
			logger.error("校验异常，异常信息:{}",e.getMessage());
			throw new RuleException("校验异常，校验失败!");
		}
	}
	
	/**
	* 描述：校验节点参数是否被使用
	* @Title: checkParamIsUsed
	* @param nodeJson
	* @param modelIdentify
	* @return
	* @author weiyongpeng
	* @date  2024年9月23日 下午4:42:53
	 */
	private boolean checkParamIsUsed(String nodeJson, String modelIdentify) {
		if (nodeJson.contains(modelIdentify)) {
			return true;
		}
		return false;
	}

	/**=================================公共参数开始=====================================*/
	
	/**
	* 描述：公共参数查询
	* @Title: listByCommonRuleParams
	* @param params
	* @return
	* @author weiyongpeng
	* @date  2024年9月15日 下午8:51:30
	 */
	@ApiOperation(value = "决策公共参数查询")
	@Get
	@Mapping("listByCommonRuleParams")
	@AuthPermissions("rule:variable:list")
	@QzLog(title = "决策公共参数查询", businessType = BusinessType.LIST)
	public PageData<Map<String,Object>> listByCommonRuleParams(Page<Map<String,Object>> page, @Param Map<String, Object> params) {
		startPage(page);
		return getPageData(ruleModelService.listByCommonRuleParams(params));
	}
	
	/**
	* 描述：非决策流参数查询
	* @Title: listByCommonRuleParams
	* @param params
	* @return
	* @author weiyongpeng
	* @date  2024年9月15日 下午8:51:30
	 */
	@ApiOperation(value = "非决策流参数查询")
	@Get
	@Mapping("listRuleParamsForH")
	@AuthPermissions("rule:variable:list")
	@QzLog(title = "非决策流参数查询", businessType = BusinessType.LIST)
	public PageData<RuleModel> listRuleParamsForH(@Param Map<String, Object> params) {
		return getPageData(ruleModelService.findRuleParamForH(params));
	}
	
	/**
	* 描述：修改公共决策参数
	* @Title: updateCommonRuleParam
	* @param ruleModel
	* @return
	* @author weiyongpeng
	* @date  2024年7月16日 下午4:21:22
	 */
	@ApiOperation(value = "决策公共参数修改")
	@Put
	@Mapping("updateCommonRuleParam")
	@AuthPermissions("rule:variable:edit")
	@QzLog(title = "决策公共参数修改", businessType = BusinessType.UPDATE)
	public Result<String> updateCommonRuleParam(@Validated @Body RuleModel ruleModel) {
		int count = ruleModelService.checkIsLinkModel(ruleModel.getId());
		if(count > 0) {
			logger.error("该参数已被决策所引用，无法修改");
			throw new RuleException("该参数已被决策所引用，无法修改");
		}else {
			if (ruleModelService.checkIsExistsFact(ruleModel.getModelIdentify()) > 1L) {
				logger.error("参数:[" + ruleModel.getModelIdentify() + "]已存在,修改失败");
				throw new RuleException("参数:[" + ruleModel.getModelIdentify() + "]已存在,修改失败");
			}
			ruleModelService.update(ruleModel);
			return Result.succeed();
		}
	}
	
	/**
	* 描述：删除根据决策参数Id
	* @Title: deleteCommonRuleParam
	* @param id
	* @return
	* @author weiyongpeng
	* @date  2024年7月16日 下午4:36:12
	 */
	@ApiOperation(value = "决策公共参数删除")
	@Delete
	@Mapping("deleteCommonRuleParam/{id}")
	@AuthPermissions("rule:variable:delete")
	@QzLog(title = "决策公共参数修改", businessType = BusinessType.UPDATE)
	public Result<String> deleteCommonRuleParam(@Path("id") String ruleModeId) {
		int count = ruleModelService.checkIsLinkModel(ruleModeId);
		if(count > 0) {
			logger.error("该参数已被决策所引用，无法删除");
			throw new RuleException("该参数已被决策所引用，无法删除");
		}
		if (ruleModelService.delete(ruleModeId)) {
			return Result.succeed("决策参数删除成功");
		}
		return Result.failure("决策参数删除失败,暂无删除数据");
	}

	/**=================================公共参数结束=====================================*/
	
	/**=================================私有参数开始=====================================*/
	
	/**
	* 描述：查询共有/私有决策设计引用参数
	* @Title: listRuleDesignParam
	* @param ruleModel
	* @return
	* @author weiyongpeng
	* @date  2024年9月16日 上午9:53:13
	 */
	@ApiOperation(value = "决策参数查询-决策设计")
	@Get
	@Mapping("listRuleDesignParam")
	@AuthPermissions("rule:variable:list")
	@QzLog(title = "查询决策参数-决策设计", businessType = BusinessType.LIST)
	public PageData<RuleModelDto> listRuleDesignParam(Page<RuleModelDto> page, @Param Map<String, Object> params) {
		startPage(page);
		return getPageData(ruleModelService.listRuleDesignParam(params));
	}
	
	/**
	* 描述：查询决策设计里参数引用列表
	* @Title: listLinkRuleDesignParams
	* @param params
	* @return
	* @author weiyongpeng
	* @date  2024年9月20日 下午7:23:39
	 */
	@ApiOperation(value = "决策引用参数查询")
	@Get
	@Mapping("listLinkRuleDesignParams")
	@AuthPermissions("rule:variable:list")
	@QzLog(title = "决策设计里参数引用列表", businessType = BusinessType.LIST)
	public PageData<Map<String,Object>> listLinkRuleDesignParams(Page<Map<String,Object>> page, @Param Map<String, Object> params) {
		startPage(page);
		params.put("isLink", "Y");
		return getPageData(ruleModelService.listByCommonRuleParams(params));
	}
	
	/**
	* 描述：决策设置调试接口参数获取
	* @Title: listDebugRuleDesignParams
	* @param params
	* @return
	* @author weiyongpeng
	* @date  2024年10月28日 上午10:20:19
	 */
	@ApiOperation(value = "决策调试引用参数查询")
	@Get
	@Mapping("listDebugRuleDesignParams")
	@AuthPermissions("rule:variable:list")
	@QzLog(title = "决策设计里调试参数引用列表", businessType = BusinessType.LIST)
	public PageData<Map<String,Object>> listDebugRuleDesignParams(@Param Map<String, Object> params) {
		return getPageData(ruleModelService.listByDebugRuleParams(params));
	}
	
	/**
	* 描述：决策设计私有参数保存
	* @Title: saveRuleDesignParam
	* @param ruleModel
	* @return
	* @author weiyongpeng
	* @date  2024年9月20日 下午12:29:14
	 */
	@ApiOperation(value = "决策私有参数新增")
	@Post
	@Mapping("saveRuleDesignParam")
	@AuthPermissions("rule:variable:add")
	@QzLog(title = "决策设计私有参数保存", businessType = BusinessType.INSERT)
	public Result<String> saveRuleDesignParam(@Validated @Body RuleModel ruleModel) {
		ruleModelService.insertRuleDesignParam(ruleModel);
		return Result.succeed();
	}
	
	/**
	* 描述：修改私有参数
	* @Title: updatePrivateRuleParam
	* @param ruleModel
	* @return
	* @author weiyongpeng
	* @date  2024年9月16日 上午9:50:07
	 */
	@ApiOperation(value = "决策私有参数修改")
	@Put
	@Mapping("updatePrivateRuleParam")
	@AuthPermissions("rule:variable:edit")
	@QzLog(title = "决策私有参数修改", businessType = BusinessType.UPDATE)
	public Result<String> updatePrivateRuleParam(@Validated @Body RuleModel ruleModel) {
		if (ruleModelService.checkIsExistsFact(ruleModel.getModelIdentify()) > 1L) {
			logger.error("参数:[" + ruleModel.getModelIdentify() + "]已存在,修改失败");
			throw new RuleException("参数:[" + ruleModel.getModelIdentify() + "]已存在,修改失败");
		} else {
			try {
				ruleModelService.update(ruleModel);
				return Result.succeed();
			} catch (Exception e) {
				logger.error("修改异常,异常信息:{}", e.getMessage());
				throw new RuleException("修改异常,修改失败!");
			}
		}
	}
	
	/**
	* 描述：删除私有/公共参数
	* @Title: delete
	* @param ruleModeId
	* @param ruleModeNodeId
	* @return
	* @author weiyongpeng
	* @date  2024年9月16日 上午9:29:41
	 */
	@ApiOperation(value = "决策私有参数删除")
	@Delete
	@Mapping("deletePrivateRuleParam")
	@AuthPermissions("rule:variable:delete")
	@QzLog(title = "决策私有参数删除", businessType = BusinessType.DELETE)
	public Result<String> deletePrivateRuleParam(@Body RuleModel ruleMode) {
		try {
			boolean deleteFlag = ruleModelService.delete(ruleMode);
			if (deleteFlag) {
				return Result.succeed("决策参数删除成功");
			}
			return Result.failure("决策参数删除失败");
		} catch (Exception e) {
			logger.error("删除异常，异常信息:{}",e.getMessage());
			throw new RuleException("删除异常，删除失败!");
		}
	}
	
	/**
	* 描述：决策设计引用公共参数
	* @Title: linkCommonParam
	* @param ruleModelNodeMergeDto
	* @return
	* @author weiyongpeng
	* @date  2024年9月16日 下午2:39:18
	 */
	@ApiOperation(value = "决策设计引用公共参数")
	@Post
	@Mapping("linkCommonParam")
	@AuthPermissions("rule:variable:add")
	@QzLog(title = "决策设计引用公共参数", businessType = BusinessType.INSERT)
	public Result<String> linkCommonParam(@Validated @Body List<RuleModelNodeMerge> ruleModelNodeMergeDto) {
		ruleModelService.insertCommonParam(ruleModelNodeMergeDto);
		return Result.succeed();
	}
	
	/**=================================私有参数结束=====================================*/
	
	/**
	* 描述：决策执行查询所有参数
	* @Title: listByRuleModelId
	* @param ruleModelId
	* @return
	* @author weiyongpeng
	* @date  2024年9月20日 下午3:44:40
	 */
	@ApiOperation(value = "决策私有参数查询")
	@Get
	@Mapping("listByRuleModelId")
	@AuthPermissions("rule:variable:list")
	@QzLog(title = "决策私有参数查询", businessType = BusinessType.LIST)
	public PageData<RuleModel> listByRuleModelId(Page<RuleModel> page, @Param String ruleModelId) {
		return getPageData(ruleModelService.listByRuleModelId(ruleModelId));
	}
	
	/**
	* 描述：删除节点同时删除参数与节点的关联关系
	* @Title: deleteRuleParamByNodeId
	* @param ruleMode
	* @return
	* @author weiyongpeng
	* @date  2024年9月21日 上午9:22:41
	 */
	@SuppressWarnings("unchecked")
	@ApiOperation(value = "删除节点同时删除参数与节点的关联关系")
	@Delete
	@Mapping("/deleteRuleParamByNodeId")
	@AuthPermissions("rule:variable:delete")
	@QzLog(title = "删除节点同时删除参数与节点的关联关系", businessType = BusinessType.DELETE)
	public Result<String> deleteRuleParamByNodeId(@Body String nodeId) {
		try {
			// 异步调用
			CompletableFuture.runAsync(()->{
				Map<Object,Object> param = (Map<Object, Object>)JSON.parse(nodeId);
				ruleModelService.deleteByNodeId(param.get("nodeId").toString());
			});
			return Result.succeed();
		} catch (Exception e) {
			logger.error("删除异常，异常信息:{}",e.getMessage());
			throw new RuleException("删除异常，删除失败!");
		}
	}
	
	/**=================================旧接口=====================================*/
	
	/**
	* 描述：根据决策id查询决策私有参数
	* @Title: listByRuleId
	* @param params
	* @return
	* @author weiyongpeng
	* @date  2024年7月20日 上午9:39:20
	 */
	@ApiOperation(value = "决策私有参数查询-老接口")
	@Get
	@Mapping("listByRuleId")
	@AuthPermissions("rule:variable:list")
	@QzLog(title = "决策私有参数查询", businessType = BusinessType.LIST)
	public PageData<RuleModel> listByRuleId(Page<RuleModel> page, @Param Map<String, Object> params) {
		RuleModel ruleModel = new RuleModel();
		// 决策id
		ruleModel.setRuleModelId(params.get("ruleModelId") == null ? "" : params.get("ruleModelId").toString());
		startPage(page);
		return getPageData(ruleModelService.listByRuleKey(ruleModel));
	}
	
	/**
	* 描述：决策私有参数保存
	* @Title: save
	* @param ruleModel
	* @return
	* @author weiyongpeng
	* @date  2024年7月16日 下午3:41:53
	 */
	@ApiOperation(value = "决策私有参数新增-老接口")
	@Post
	@Mapping("save")
	@AuthPermissions("rule:variable:add")
	@QzLog(title = "决策私有参数保存", businessType = BusinessType.INSERT)
	public Result<String> save(/* @Validated */@Body RuleModel ruleModel) {
		// 检查参数名是否存在
		RuleModel _ruleModel = ruleModelService.checkRuleModel(ruleModel,"add");
		if (null == _ruleModel) {
			ruleModelService.insert(ruleModel);
		} else {
			logger.error("已存在名称为[" + ruleModel.getName() + "]的参数，或唯一标识["+ruleModel.getModelIdentify() +"]已存在");
			throw new RuleException("已存在名称为[" + ruleModel.getName() + "]的参数，或唯一标识["+ruleModel.getModelIdentify() +"]已存在");
		}
		return Result.succeed();
	}
	
	/**
	* 描述：修改私有决策参数
	* @Title: update
	* @param ruleModel
	* @return
	* @author weiyongpeng
	* @date  2024年7月16日 下午4:21:22
	 */
	@ApiOperation(value = "决策私有参数修改-老接口")
	@Put
	@Mapping("update")
	@AuthPermissions("rule:variable:edit")
	@QzLog(title = "决策私有参数修改", businessType = BusinessType.UPDATE)
	public Result<String> update(@Validated @Body RuleModel ruleModel) {
		RuleModel _ruleModel = ruleModelService.checkRuleModel(ruleModel,"update");
		// 如果参数的name属性
		if(_ruleModel != null && (_ruleModel.getName().equals(ruleModel.getName()) && _ruleModel.getModelIdentify().equals(ruleModel.getModelIdentify()))) {
			ruleModelService.update(ruleModel);
		}else {
			logger.error("参数名name和参数唯一标识ruleModelIdentify不能修改");
			throw new RuleException("参数名name和参数唯一标识ruleModelIdentify不能修改");
		}
		return Result.succeed();
	}
	
	/**
	* 描述：删除根据决策参数Id
	* @Title: delete
	* @param ruleModeId
	* @return
	* @author weiyongpeng
	* @date  2024年7月16日 下午4:36:12
	 */
	@ApiOperation(value = "决策私有参数删除-老接口")
	@Delete
	@Mapping("delete/{ruleModeId}")
	@AuthPermissions("rule:variable:delete")
	@QzLog(title = "决策私有参数修改", businessType = BusinessType.UPDATE)
	public Result<String> delete(@Path("ruleModeId") String ruleModeId) {
		boolean deleteFlag = ruleModelService.delete(ruleModeId);
		if (deleteFlag) {
			return Result.succeed("决策参数删除成功");
		}
		return Result.failure("决策参数删除,暂无删除数据");
	}
	
	/**
	* 描述：sql参数查询
	* @Title: listRuleModelInner
	* @param sqlParamName
	* @return
	* @author weiyongpeng
	* @date  2024年11月30日 下午4:31:34
	 */
	@Get
	@Mapping("listSqlParamInner")
	public Result<RuleSqlModelDto> listRuleModelInner(@Param("sqlParamName") String sqlParamName) {
		RuleSqlModelDto ruleModel = ruleModelService.findSqlParamByName(sqlParamName);
		return Result.succeed(ruleModel);
	}
}
